<template>
  <div>
    <el-card class="mt-10">
      <el-form
        label-width="100px"
        ref="spuFormRef"
        :model="spuFormData"
        :rules="spuFormRules"
      >
        <el-form-item label="SPU名称" prop="spuName">
          <el-input placeholder="SPU名称" v-model="spuFormData.spuName" />
        </el-form-item>
        <el-form-item label="品牌" prop="tmId">
          <el-select placeholder="请选择品牌" v-model="spuFormData.tmId">
            <el-option
              v-for="trademark in acceptAllTrademark"
              :key="trademark.id"
              :label="trademark.tmName"
              :value="trademark.id"
            />
          </el-select>
        </el-form-item>
        <el-form-item label="SPU描述" prop="description">
          <el-input
            type="textarea"
            placeholder="SPU描述"
            v-model="spuFormData.description"
          />
        </el-form-item>
        <el-form-item label="SPU图片" prop="spuImageList">
          <el-upload
            v-model:file-list="spuFormData.spuImageList"
            :action="`${BASE_URL}/admin/product/fileUpload`"
            list-type="picture-card"
            :before-upload="beforeAvatarUpload"
            :on-success="uploadImgSuccess"
            :limit="IMG_UPLOAD_MAX"
            class="formImg"
            :on-preview="handlePictureCardPreview"
          >
            <el-icon><Plus /></el-icon>
            <el-dialog v-model="dialogVisible" width="50%">
              <img
                class="formImgPreview"
                w-full
                :src="dialogImageUrl"
                alt="Preview Image"
              />
            </el-dialog>
          </el-upload>
        </el-form-item>
        <el-form-item label="销售属性" prop="spuSaleAttrList">
          <el-select
            :placeholder="
              filterBaseAttrListInOption.length
                ? `还剩${filterBaseAttrListInOption.length}个未选择`
                : '没有可添加的属性哦'
            "
            width="400px"
            v-model="selectBaseAttrRef"
          >
            <el-option
              v-for="saleAttrList in filterBaseAttrListInOption"
              :key="saleAttrList.id"
              :label="saleAttrList.name"
              :value="`${saleAttrList.id}:${saleAttrList.name}`"
            />
          </el-select>
          <el-button
            type="primary"
            :disabled="!selectBaseAttrRef"
            :icon="Plus"
            @click="addSaleAttr"
            >添加销售属性</el-button
          >
          <el-table border class="mt-10" :data="spuFormData.spuSaleAttrList">
            <el-table-column
              label="序号"
              type="index"
              width="80"
              align="center"
            />
            <el-table-column
              label="属性名"
              prop="saleAttrName"
              width="260"
              align="center"
            />
            <el-table-column label="属性值列表" width="500px">
              <!-- closable 用来判断是否可关闭 -->
              <template v-slot="{ row }">
                <el-tag
                  class="mr-10"
                  v-for="(saleAttrValue, index) in row.spuSaleAttrValueList"
                  :key="saleAttrValue.saleAttrValueName"
                  closable
                  @close="delSaleAttrValue(row.spuSaleAttrValueList, index)"
                  >{{ saleAttrValue.saleAttrValueName }}</el-tag
                >
                <el-input
                  size="small"
                  v-if="row.isEdit"
                  class="attrInput"
                  ref="inputRef"
                  v-model="saleAttrValueName"
                  @blur="inputShow(row)"
                />
                <el-button
                  size="small"
                  :icon="Plus"
                  v-else
                  @click="inputEdit(row)"
                />
              </template>
            </el-table-column>
            <el-table-column label="操作">
              <template #default="{ row }">
                <el-button
                  type="danger"
                  :icon="Delete"
                  size="small"
                  @click="deleteSaleAttrItem(row.index)"
                />
              </template>
            </el-table-column>
          </el-table>
        </el-form-item>
      </el-form>
      <el-button type="primary" @click="addOrUpdateSpuItem">保存</el-button>
      <el-button @click="isShowSpuList">取消</el-button>
    </el-card>
  </div>
</template>

<script lang="ts">
export default {
  name: "addOrUpdateList",
};
</script>

<script lang="ts" setup>
import { computed, onMounted, reactive, ref, nextTick } from "vue";
import { Delete, Plus } from "@element-plus/icons-vue";
import { getAllTrademark } from "@/api/product/trademark";
import {
  GetSaleAttrListApi,
  getAddAttrApi,
  getSpuImgListApi,
  getSpuSaleAttrListApi,
  getUpdateSpuInfoApi,
} from "@/api/product/spu";
import type { ITrademarkList } from "@/api/product/model/trademark";
import type {
  GetSaleAttrList,
  SpuSaleAttrList,
  SpuFormData,
  SpuSaleAttrItem,
  SpuSaleAttrValueList,
} from "@/api/product/model/spuModel";
import { ElMessage } from "element-plus";
import type { FormInstance, FormRules, UploadProps } from "element-plus";
import { useCategoryStore } from "@/stores/category";
import { useSpuStore } from "@/stores/spu";

const saleAttrValueName = ref("");
/**************销售属性表单验证*******************/
const saleAttrListValidator = (
  rule: any,
  value: SpuSaleAttrList,
  callback: any
) => {
  // rule 当前校验规则的信息
  // value 当前校验表单的数据 spuSaleAttrList的值
  // 销售属性的验证规则
  if (!value.length) {
    callback(new Error("请添加一个或多个销售属性"));
    // callback是一个函数，需要调用，callback()不传参数，表示校验通过 callback(new Error('xxx'))传参数，就是校验失败
    // 传递的参数就是我们输入的错误提示信息
    return;
  }
  // 销售属性的销售属性值验证规则
  if (!value.every((saleAttr) => saleAttr.spuSaleAttrValueList.length)) {
    callback(new Error("销售属性下面也要记得添加销售属性值哦"));
    return;
  }
  callback();
};

/************** 显示和编辑模式 *******************/
// 编辑模式
// const attrTagInputRef = ref();
const inputRef = ref();
const inputEdit = async (row: SpuSaleAttrItem) => {
  row.isEdit = true;
  await nextTick();
  inputRef.value.focus();
};
const inputShow = (row: SpuSaleAttrItem) => {
  row.isEdit = false;
  if (saleAttrValueName.value) {
    row.spuSaleAttrValueList.push({
      baseSaleAttrId: row.baseSaleAttrId,
      saleAttrValueName: saleAttrValueName.value,
    });
    saleAttrValueName.value = "";
  }
};
const delSaleAttrValue = (
  spuSaleAttrValueList: SpuSaleAttrValueList,
  index: number
) => {
  spuSaleAttrValueList.splice(index, 1);
};
/*************** 销售属性功能 ********************/
const selectBaseAttrRef = ref("");
// 删除属性
// const deleteSaleAttrItem = (index: number) => {
//   spuFormData.spuSaleAttrList.splice(index, 1);
// };
const deleteSaleAttrItem = (index: number) => {
  spuFormData.spuSaleAttrList.splice(index, 1);
};
// 下拉框中过滤基础属性列表
const filterBaseAttrListInOption = computed(() => {
  return acceptSaleAttrList.value.filter((saleAttrList) => {
    return !spuFormData.spuSaleAttrList.some(
      (spuSaleAttr) => spuSaleAttr.baseSaleAttrId === saleAttrList.id
    );
  });
});
// 添加属性
const addSaleAttr = () => {
  const [id, name] = selectBaseAttrRef.value.split(":");
  spuFormData.spuSaleAttrList.push({
    baseSaleAttrId: +id,
    saleAttrName: name,
    spuSaleAttrValueList: [],
    isEdit: false,
  });
  selectBaseAttrRef.value = "";
};
/***************** 提交表单 ****************/
const categoryStore = useCategoryStore();
const addOrUpdateSpuItem = async () => {
  const id = spuStore.id;
  const data = {
    ...spuFormData,
    tmId: spuFormData.tmId as number,
    category3Id: categoryStore.category3Id as number,
    spuImageList: spuFormData.spuImageList.map((img) => {
      return {
        imgName: img.name,
        imgUrl: img.response
          ? (img.response as { data: string }).data
          : (img.url as string),
        //? (img.response as any).data : img.url,
        // (img.response as { data: string }).data 这个方法为什么不行呢？
        // 把response断言成一个对象，然后再把里面的data断言成string
      };
    }),
  };
  await spuFormRef.value?.validate();
  if (id) {
    await getUpdateSpuInfoApi({
      ...data,
      id,
    });
  } else {
    await getAddAttrApi({
      ...data,
    });
  }
  ElMessage.success(`${id ? "修改" : "添加"}SPU成功`);
  isShowSpuList();
};

/*********** 上传图片 **********/
const BASE_URL = import.meta.env.VITE_API_URL;
// 预览
const dialogImageUrl = ref("");
const dialogVisible = ref(false);
const handlePictureCardPreview: UploadProps["onPreview"] = (uploadFile) => {
  dialogImageUrl.value = uploadFile.url as string;
  dialogVisible.value = true;
};

// 图片上传之前
const beforeAvatarUpload: UploadProps["beforeUpload"] = (rawFile) => {
  const validImageType = ["image/jpg", "image/jpeg", "image/png"];
  if (!validImageType.includes(rawFile.type)) {
    ElMessage.error("图片类型只能是jpeg、jpg或png格式!");
    return false;
  } else if (rawFile.size / 1024 > 250) {
    ElMessage.error("图片超过了250kb哦~~");
    return false;
  }
  return true;
};
// 上传成功
const uploadImgSuccess = () => {
  if (spuFormData.spuImageList.length > 1) {
    spuFormRef.value?.clearValidate(["spuImageList"]);
  }
};
// 上传图片达到限制数不显示添加按钮
const IMG_UPLOAD_MAX = 5;
const isShowImgBtn = computed(() => {
  return spuFormData.spuImageList.length < IMG_UPLOAD_MAX
    ? "inline-flex"
    : "none";
});
// 声明两个空数组来接收品牌和销售属性的数据
const acceptAllTrademark = ref<ITrademarkList>([]);
const acceptSaleAttrList = ref<GetSaleAttrList>([]);
const emit = defineEmits(["setIsShow"]);
// 表单三部曲
const spuFormRef = ref<FormInstance>();

// 整个表单数据
const spuStore = useSpuStore();
const spuFormData = reactive<SpuFormData>({
  // 里面每个名称都要跟接口文档一一对应，别再乱改了
  spuName: spuStore.spuName,
  tmId: spuStore.tmId,
  description: spuStore.description,
  spuImageList: [],
  spuSaleAttrList: [],
});

// 表单的校验规则
const spuFormRules = reactive<FormRules>({
  // 规则名称必须和数据名称一致
  spuName: [{ required: true, message: "请输入SPU名称", trigger: "blur" }],
  tmId: [{ required: true, message: "请选择品牌", trigger: "change" }],
  description: [{ required: true, message: "请输入SPU描述", trigger: "blur" }],
  spuImageList: [{ required: true, message: "请上传图片哦！" }],
  spuSaleAttrList: [
    { required: true, validator: saleAttrListValidator, trigger: "blur" },
  ],
});

// 获取所有品牌
onMounted(async () => {
  acceptAllTrademark.value = await getAllTrademark();
});
// 获取销售属性
onMounted(async () => {
  acceptSaleAttrList.value = await GetSaleAttrListApi();
});
// 获取spuImageList
onMounted(async () => {
  const id = spuStore.id;
  if (id) {
    const spuImageList = await getSpuImgListApi(id);
    spuFormData.spuImageList = spuImageList.map((img) => {
      return {
        name: img.imgName,
        url: img.imgUrl,
      };
    });
  }
});
onMounted(async () => {
  const id = spuStore.id;
  if (id) {
    spuFormData.spuSaleAttrList = await getSpuSaleAttrListApi(id);
  }
});

// 显示SPU列表
const isShowSpuList = () => {
  emit("setIsShow", 1);
};
</script>

<style scoped>
.formImg:deep(.el-upload) {
  display: v-bind(isShowImgBtn);
}
.formImgPreview {
  width: 100%;
}
.attrInput {
  width: 110px;
}
</style>
